/***************************************************************************
 *   Copyright (C) 2008 by Chris Vickery   *
 *   chrisinajar@gmail.com   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#include "mainapplication.h"

#include <QApplication>
#include <QDebug>
#include <QDesktopWidget>
#include <QTimer>
#include <QTime>
#include <GL/gl.h>
#include <GL/glu.h>
#include "spaceship.h"

#define FRAME_LIMIT 25

MainApplication::MainApplication(QObject *parent) :
		QObject(parent),
		timer(0, 0, 0, 0)
{
	ship = new SpaceShip(this);
	timer.start();
	i = 0;
	QRect screenr(QApplication::desktop()->screenGeometry());
	height = screenr.height() / 2;
	width = screenr.width() / 2;
	if (SDL_Init(SDL_INIT_AUDIO | SDL_INIT_VIDEO) < 0)
	{
		qDebug() << "Unable to init SDL: " << SDL_GetError();
		exit(1);
	}
	atexit(SDL_Quit);

	SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 5);
	SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 5);
	SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 5);
	SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
	SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);

	screen = SDL_SetVideoMode(width, height, 32, SDL_HWSURFACE | SDL_HWPALETTE | SDL_ANYFORMAT | SDL_OPENGL);
	if (screen == NULL)
	{
		qFatal(QString("Couldn't set %1x%2x%3 video mode %4").arg(screenr.width()).arg(screenr.height()).arg("x").arg(32).arg(SDL_GetError()).toAscii().data());
	}
	QTimer* t = new QTimer(this);
	t->setInterval(0);
	connect(t, SIGNAL(timeout()), this, SLOT(iterate()));
	t->start();
// 	QTimer::singleShot(5000, qApp, SLOT(quit()));
	SDL_WM_SetCaption("EV MMO", "");
// 	glViewport(0,0,100,100);
	glOrtho(0, width, 0, height, -10, 10);
}

void MainApplication::iterate()
{
	Uint32 rmask, gmask, bmask, amask;
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
	rmask = 0xff000000;
	gmask = 0x00ff0000;
	bmask = 0x0000ff00;
	amask = 0x000000ff;
#else
	rmask = 0x000000ff;
	gmask = 0x0000ff00;
	bmask = 0x00ff0000;
	amask = 0xff000000;
#endif

	int elapsed = timer.elapsed();
	if (elapsed < FRAME_LIMIT)
	{
		usleep((FRAME_LIMIT - elapsed)*1000);
		elapsed = FRAME_LIMIT;
	}
	timer.restart();
	SDL_Event event;
	while (SDL_PollEvent(&event))
	{
		/* We are only worried about SDL_KEYDOWN and SDL_KEYUP events */
		switch (event.type)
		{
			case SDL_KEYDOWN:
				pressedKeys |= sdlKeyToKey(event.key.keysym.sym);
				break;

			case SDL_KEYUP:
				pressedKeys &= !(sdlKeyToKey(event.key.keysym.sym));
				break;
			default:
				break;
		}
	}
	if (pressedKeys & KeyW)
	{
		qDebug() << "W";
		ship->accelerate(elapsed);
	}
	if (pressedKeys & KeyS)
	{
		qDebug() << "S";
		ship->accelerate(-elapsed);
	}
	if (pressedKeys & KeyD)
	{
		qDebug() << "D";
		ship->rotate(elapsed);
	}
	if (pressedKeys & KeyA)
	{
		qDebug() << "A";
		ship->rotate(-elapsed);
	}
	if (pressedKeys & KeyQ)
	{
		qApp->quit();
	}
	ship->tick(elapsed);
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	glViewport(0, 0, width, height);

	glPushMatrix();
	
	glRotated(ship->getAngle(), 0, 0, 1);
	
	glBegin(GL_POLYGON);

	
	glVertex2f(ship->getX(), ship->getY());
	glVertex2f(ship->getX(), ship->getY() + ship->getHeight());
	glVertex2f(ship->getX() + ship->getWidth(), ship->getY() + ship->getHeight());
	glVertex2f(ship->getX() + ship->getWidth(), ship->getY());

	glEnd();
	glPopMatrix();
	qDebug() << ship->getAngle();

	SDL_GL_SwapBuffers();
}

MainApplication::Key MainApplication::sdlKeyToKey(SDLKey k)
{
	switch (k)
	{
		case SDLK_a:
			return KeyA;
			break;
		case SDLK_b:
			return KeyB;
			break;
		case SDLK_c:
			return KeyC;
			break;
		case SDLK_d:
			return KeyD;
			break;
		case SDLK_e:
			return KeyE;
			break;
		case SDLK_f:
			return KeyF;
			break;
		case SDLK_g:
			return KeyG;
			break;
		case SDLK_h:
			return KeyH;
			break;
		case SDLK_i:
			return KeyI;
			break;
		case SDLK_j:
			return KeyJ;
			break;
		case SDLK_k:
			return KeyK;
			break;
		case SDLK_l:
			return KeyL;
			break;
		case SDLK_m:
			return KeyM;
			break;
		case SDLK_n:
			return KeyN;
			break;
		case SDLK_o:
			return KeyO;
			break;
		case SDLK_p:
			return KeyP;
			break;
		case SDLK_q:
			return KeyQ;
			break;
		case SDLK_r:
			return KeyR;
			break;
		case SDLK_s:
			return KeyS;
			break;
		case SDLK_t:
			return KeyT;
			break;
		case SDLK_u:
			return KeyU;
			break;
		case SDLK_v:
			return KeyV;
			break;
		case SDLK_w:
			return KeyW;
			break;
		case SDLK_x:
			return KeyX;
			break;
		case SDLK_y:
			return KeyY;
			break;
		case SDLK_z:
			return KeyZ;
			break;
		default:
			break;
	}
}

MainApplication::~MainApplication()
{
}



